package com.sll.hosptials.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.TreeNode;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sll.hosptials.controller.req.*;
import com.sll.hosptials.controller.resp.LoginResp;
import com.sll.hosptials.controller.resp.UserDetailResp;
import com.sll.hosptials.controller.resp.UserInfoPageResp;
import com.sll.hosptials.listener.ExcelListener;
import com.sll.hosptials.model.DictInfo;
import com.sll.hosptials.model.UserInfo;
import com.sll.hosptials.model.UserOrg;
import com.sll.hosptials.model.UserRole;
import com.sll.hosptials.service.ExcelService;
import com.sll.hosptials.service.UserInfoService;
import com.sll.hosptials.mapper.UserInfoMapper;
import com.sll.hosptials.service.UserOrgService;
import com.sll.hosptials.service.UserRoleService;
import com.sll.hosptials.utils.JwtUtil;
import com.sll.hosptials.vo.ServiceException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.sll.hosptials.config.ParamConfig.TOKEN;

/**
 * @author shaolulu
 * @description 针对表【user_info(用户表)】的数据库操作Service实现
 * @createDate 2024-01-02 14:22:09
 */
@Service
@Transactional
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;
    @Resource
    private UserOrgService userOrgService;
    @Resource
    private UserRoleService userRoleService;
    @Autowired
    RedisTemplate redisTemplate;
    @Resource
    private ExcelService excelService;

    @Override
    public Page<UserInfoPageResp> page(UserInfoPageReq userInfoPageReq) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNoneBlank(userInfoPageReq.getUserName()),UserInfo::getUserName,userInfoPageReq.getUserName());
        queryWrapper.orderByDesc(UserInfo::getCreateDateTime);
        Page<UserInfo> page = this.page(new Page<>(userInfoPageReq.getPageNo(), userInfoPageReq.getPageSize()), queryWrapper);
        IPage<UserInfoPageResp> result = page.convert(userInfo -> {
            UserInfoPageResp userInfoPageResp = new UserInfoPageResp();
            BeanUtil.copyProperties(userInfo, userInfoPageResp);
            return userInfoPageResp;
        });
        return (Page<UserInfoPageResp>) result;
    }

    @Override
    public LoginResp login(LoginReq req) {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.isNoneBlank(req.getUserName()), UserInfo::getUserName, req.getUserName())
                .eq(UserInfo::getPassword, req.getPassword());
        UserInfo userInfo = Optional.ofNullable(this.getOne(queryWrapper, false))
                .orElseThrow(() -> new ServiceException("账户信息不存在"));
        LoginResp loginResp = new LoginResp();
        BeanUtil.copyProperties(userInfo, loginResp);
//        redis存储token
        redisTemplate.opsForValue().set(TOKEN, userInfo.getUserName());
        String jwtToken = JwtUtil.createJwtToken("123");
        System.out.println(jwtToken);
        loginResp.setToken(jwtToken);
        return loginResp;
    }

    @Override
    public Boolean addOrUpdateUserInfo(AddUserInfoReq req) {
        boolean flag = Boolean.TRUE;
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUserName, req.getUserName());
        queryWrapper.ne(Objects.nonNull(req.getUserId()), UserInfo::getUserId, req.getUserId());
        if (Optional.ofNullable(this.getOne(queryWrapper)).isPresent()) {
            throw new ServiceException("用户名:" + req.getUserName() + "已存在，不能重复");
        }
        UserInfo userInfo = JSONObject.parseObject(JSONObject.toJSONString(req), UserInfo.class);
        flag = this.saveOrUpdate(userInfo);
//        分配用户组织
        addUserOrg(userInfo, req.getOrgIds());
//        用户分配角色
        addUserRole(userInfo, req.getRoleIds());
        return flag;
    }

    @Override
    public Boolean delUserInfo(IdsReq req) {
        return null;
    }

    @Override
    public Boolean disableUser(IdReq req) {
        return null;
    }

    @Override
    public UserDetailResp userDetail(IdReq req) {
        UserInfo userInfo = Optional.ofNullable(this.getById(req.getId()))
                .orElseThrow(() -> new ServiceException("不存在用户id为:" + req.getId() + "的数据"));
        UserDetailResp userDetailResp = BeanUtil.copyProperties(userInfo, UserDetailResp.class);
        LambdaQueryWrapper<UserOrg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserOrg::getUserId, userInfo.getUserId());
        List<UserOrg> list = userOrgService.list(queryWrapper);
        userDetailResp.setUserOrgs(list);
        LambdaQueryWrapper<UserRole> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(UserRole::getUserId, userInfo.getUserId());
        List<UserRole> roleList = userRoleService.list(queryWrapper1);
        userDetailResp.setUserRoles(roleList);
        return userDetailResp;
    }

    @Override
    public List<DictInfo> getHutoolTree() {
        List<UserInfo> list = this.list();
        List<TreeNode<String>> nodeList = new LinkedList<>();

//        TreeUtil.build();
        return null;
    }

    @Override
    public Boolean importUserInfo(MultipartFile multipartFile) throws IOException {
        EasyExcel.read(multipartFile.getInputStream(),
                UserInfo.class,
                new ExcelListener<>(excelService))
                .sheet()
                .doRead();
        return true;
    }

    @Override
    public Boolean delete(IdReq req) {

        return this.removeById(req.getId());
    }

    /**
     * 分配用户组织
     *
     * @param userInfo
     * @param orgIdList
     */
    private void addUserOrg(UserInfo userInfo, List<Long> orgIdList) {
        LambdaQueryWrapper<UserOrg> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(UserOrg::getUserId, userInfo.getUserId());
        List<UserOrg> list = userOrgService.list(queryWrapper1);
//            数据库中存在数据
        List<Long> orgIds = list.stream().map(UserOrg::getOrgId).collect(Collectors.toList());
//            新入参存在，但数据不存在，则新增
        List<Long> bzcList = CollectionUtil.subtractToList(orgIdList, orgIds);
        for (Long orgId : bzcList) {
            userOrgService.save(UserOrg.builder().userId(userInfo.getUserId()).orgId(orgId).build());
        }
//            以新入参的数据为依据，比较数据库中存在，但新入参的不存在，则删除
        List<Long> czList = CollectionUtil.subtractToList(orgIds, orgIdList);
        if (CollectionUtil.isNotEmpty(czList)) {
            queryWrapper1.in(UserOrg::getOrgId, czList);
            userOrgService.remove(queryWrapper1);
        }
    }

    /**
     * 分配用户角色
     *
     * @param userInfo
     * @param roleIds
     */
    private void addUserRole(UserInfo userInfo, List<Long> roleIds) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userInfo.getUserId());
        List<UserRole> userRoles = userRoleService.list(queryWrapper);
        List<Long> userRoleList = CollectionUtil.newArrayList();
        if (CollectionUtil.isNotEmpty(userRoles)) {
            userRoleList = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        }
        List<Long> addData = CollectionUtil.subtractToList(roleIds, userRoleList);
        if (CollectionUtil.isNotEmpty(addData)) {
            for (Long roleId : addData) {
                userRoleService.save(UserRole.builder().roleId(roleId).userId(userInfo.getUserId()).build());
            }
        }
        List<Long> delData = CollectionUtil.subtractToList(userRoleList, roleIds);
        if (CollectionUtil.isNotEmpty(delData)) {
            queryWrapper.in(UserRole::getRoleId, delData);
            userRoleService.remove(queryWrapper);
        }
    }

//    public static void main(String[] args) {
//
//        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
//
//        // 构建node列表(数据源)
//        List<TreeNode<String>> nodeList = CollUtil.newArrayList();
//        TreeNode<String> treeNode = new TreeNode<>("1", "0", "系统管理", 5);
//        HashMap<String, Object> hashMap = new HashMap<>();
//        hashMap.put("dictCode", "code123");
//        treeNode.setExtra(hashMap);
//        nodeList.add(treeNode);
//        nodeList.add(new TreeNode<>("1", "0", "系统管理", 5));
//        nodeList.add(new TreeNode<>("11", "1", "用户管理", 222222));
//        nodeList.add(new TreeNode<>("111", "11", "用户添加", 0));
//        nodeList.add(new TreeNode<>("2", "0", "店铺管理", 1));
//        nodeList.add(new TreeNode<>("21", "2", "商品管理", 1));
//        nodeList.add(new TreeNode<>("221", "2", "商品管理2", 2));
//        // 0表示最顶层的id是0
////        List<Tree<String>> treeList = TreeUtil.build(nodeList, "-1",treeNodeConfig,
////                (treeNode, tree) -> {
////                    tree.setId(treeNode.getId());
////                    tree.setParentId(treeNode.getParentid());
////                    tree.setName(treeNode.getIsAuthorName());
////                    //扩展属性
////                    tree.putExtra("total",treeNode.getTotal());
////                    tree.putExtra("dispatchnoId",treeNode.getDispatchnoId());
////                });
////        System.out.println(JSONUtil.toJsonStr(treeList));
//
//    }

//    public static void main(String[] args) {
//        ArrayList<Integer> list1 = ListUtil.toList(1, 2, 3, 3);
//        ArrayList<Integer> list2 = ListUtil.toList(3, 4, 5);
//        List<Integer> list = CollectionUtil.subtractToList(list1, list2);
//        System.out.println("集合1-2==:" + list);
//        List<Integer> list21 = CollectionUtil.subtractToList(list2, list1);
//        System.out.println(list21);
//
//    }

}




